import inspect
import json
import os
from app.utils.exceptions import ConfigLoadFailedError


# ====================== 配置类 ======================
class EnvConfig:
    """集中管理配置"""

    def __init__(self):
        # 创建正向映射
        self.material_type_mapping = self._load_mapping('MATERIAL_TYPE_MAPPING')
        self.dept_field_mapping = self._load_mapping('DEPT_FIELD_MAPPING')

        # 创建反向映射
        self.reverse_material_type_mapping = {v: k for k, v in self.material_type_mapping.items()}
        self.reverse_dept_field_mapping = {v: k for k, v in self.dept_field_mapping.items()}

    @property
    def JWT_SECRET_KEY(self):
        value = os.getenv('JWT_SECRET_KEY')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "JWT_SECRET_KEY 环境变量未设置！"})
        return value

    @property
    def AES_GCM_SECRET_KEY(self):
        value = os.getenv('AES_GCM_SECRET_KEY')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "AES_GCM_SECRET_KEY 环境变量未设置！"})
        return value

    @property
    def FERNET_SECRET_KEY(self):
        value = os.getenv('FERNET_SECRET_KEY')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "FERNET_SECRET_KEY 环境变量未设置！"})
        return value

    @property
    def JWT_ALGORITHM(self):
        value = os.getenv('JWT_ALGORITHM')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "JWT_ALGORITHM 环境变量未设置！"})
        return value

    @property
    def ACCESS_EXPIRE_MINUTES(self):
        value = os.getenv('ACCESS_EXPIRE_MINUTES')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "ACCESS_EXPIRE_MINUTES 环境变量未设置！"})
        return int(value)

    @property
    def REFRESH_EXPIRE_DAYS(self):
        value = os.getenv('REFRESH_EXPIRE_DAYS')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "REFRESH_EXPIRE_DAYS 环境变量未设置！"})
        return int(value)

    @property
    def BIGDATA_DATABASE_URL(self):
        value = os.getenv('BIGDATA_DATABASE_URL')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "BIGDATA_DATABASE_URL 环境变量未设置！"})
        return value

    @property
    def TEACHER_MANAGEMENT_DATABASE_URL(self):
        value = os.getenv('TEACHER_MANAGEMENT_DATABASE_URL')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "TEACHER_MANAGEMENT_DATABASE_URL 环境变量未设置！"})
        return value

    @property
    def SZH_INFO_DATABASE_URL(self):
        value = os.getenv('SZH_INFO_DATABASE_URL')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "SZH_INFO_DATABASE_URL 环境变量未设置！"})
        return value

    @property
    def SZH_MANAGEMENT_DATABASE_URL(self):
        value = os.getenv('SZH_MANAGEMENT_DATABASE_URL')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "SZH_MANAGEMENT_DATABASE_URL 环境变量未设置！"})
        return value

    @property
    def LOCAL_TEACHING_MANAGEMENT_DATABASE_URL(self):
        value = os.getenv('LOCAL_TEACHING_MANAGEMENT_DATABASE_URL')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "LOCAL_TEACHING_MANAGEMENT_DATABASE_URL 环境变量未设置！"})
        return value

    @property
    def COOKIE_DOMAIN(self):
        value = os.getenv('COOKIE_DOMAIN')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "COOKIE_DOMAIN 环境变量未设置！"})
        return value

    @property
    def FLASK_ENV(self):
        value = os.getenv('FLASK_ENV')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "FLASK_ENV 环境变量未设置！"})
        return value

    @property
    def TOKEN_PREFIX(self):
        value = os.getenv('TOKEN_PREFIX')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "TOKEN_PREFIX 环境变量未设置！"})
        return value

    @property
    def ALLOWED_ROLES(self):
        value = os.getenv('ALLOWED_ROLES')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "ALLOWED_ROLES 环境变量未设置！"})
        return value.split(',')

    @property
    def BASE_PATH(self):
        value = os.getenv('BASE_PATH')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "BASE_PATH 环境变量未设置！"})
        return value

    @property
    def TEMP_PATH(self):
        value = os.getenv('TEMP_PATH')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "TEMP_PATH 环境变量未设置！"})
        return value

    @property
    def BACKUP_PATH(self):
        value = os.getenv('BACKUP_PATH')
        if not value:
            raise ConfigLoadFailedError({"o-facingMsg": "BACKUP_PATH 环境变量未设置！"})
        return value

    def _load_mapping(self, env_name):
        """从环境变量加载映射"""
        mapping_str = os.getenv(env_name)
        if mapping_str:
            try:
                return json.loads(mapping_str)
            except json.JSONDecodeError:
                raise ConfigLoadFailedError({"o-facingMsg": f"警告: {env_name} 解析失败"})
        return {}

    def validate_configs(self):
        """检测环境变量是否配置"""
        # 获取所有 @property 属性名
        properties = [
            name for name, _ in inspect.getmembers(self.__class__, lambda o: isinstance(o, property))
        ]

        # 逐个访问属性以触发检查
        for prop_name in properties:
            _ = getattr(self, prop_name)  # 访问属性，触发可能的异常


ENV_CONFIG = EnvConfig()
